#include<stdio.h>
#include<stdint.h>
#include <string.h>

typedef struct 
{
	uint8_t PREAMBLE[5];
	uint8_t START;
	uint8_t ADDR[5];
	uint8_t COM;
	uint8_t BCNT;
	uint8_t STATUS[2];
	uint8_t DATA[25];
	uint8_t CHK;
}HART_Struct;

HART_Struct trans_HART_to_Struct(uint8_t * buf)
{
    HART_Struct HART_Stu;
    uint8_t i=0;
    uint8_t START_Num=0;
    uint8_t COM_Num=0;
    uint8_t CHK_Num=0;
    uint8_t Check_Sum=0;  
    if(buf[0]==0xFF)
    {                
        for(i=0;i<6;i++)
        {            
            if(buf[i]!=0xFF)
            {
                HART_Stu.START=buf[i];
                START_Num=i;                
                break;
            }
            START_Num=i;
        }

        if(START_Num<2)
        {
            return HART_Stu;
        }

        for(i=0;i<START_Num;i++)
        {
            HART_Stu.PREAMBLE[i]=buf[i];
        }
        
        if(HART_Stu.START<0x10)
        {
            COM_Num=START_Num+2;            
        }
        else
        {
            COM_Num=START_Num+6;            
        }
        for(i=0;i<COM_Num-START_Num-1;i++)
        {
            HART_Stu.ADDR[i]=buf[START_Num+1+i];
        }

        HART_Stu.COM=buf[COM_Num];
        HART_Stu.BCNT=buf[COM_Num+1];
        CHK_Num=COM_Num+HART_Stu.BCNT+2;
        HART_Stu.CHK=buf[CHK_Num];

        for(i=START_Num;i<CHK_Num;i++)
        {
            Check_Sum=Check_Sum^buf[i];
        }
        if(HART_Stu.CHK==Check_Sum)
        {
            if(HART_Stu.BCNT>0)
            {
                if(HART_Stu.BCNT>1 && (HART_Stu.START&0x0F)==0x06)
                {                  
                    for(i=0;i<2;i++)
                    {
                        HART_Stu.STATUS[i]=buf[COM_Num+2+i];
                    }
                    for(i=0;i<HART_Stu.BCNT-2;i++)
                    {
                        HART_Stu.DATA[i]=buf[COM_Num+4+i];
                    }
                }
                else
                {
                    for(i=0;i<HART_Stu.BCNT;i++)
                    {
                        HART_Stu.DATA[i]=buf[COM_Num+2+i];
                    }
                }
            }
            else
            {
                return HART_Stu;
            }
        }
        else
        {
            return HART_Stu;
        }
    }
    else
    {
        return HART_Stu;
    }
    return HART_Stu;
}

int8_t trans_HART_to_Buf(HART_Struct HART_Stu,uint8_t * buf)
{
    uint8_t i=0;
    uint8_t START_Num=0;
    uint8_t COM_Num=0;
    uint8_t CHK_Num=0;
    uint8_t Check_Sum=0;

    if(HART_Stu.PREAMBLE[0]==0xFF)
    {
        for(i=0;i<6;i++)
        {            
            if(HART_Stu.PREAMBLE[i]!=0xFF)
            {
                buf[i]=HART_Stu.START;
                START_Num=i;                
                break;
            }            
            START_Num=i;
        }

        if(START_Num<2)
        {
            return -1;
        }

        for(i=0;i<START_Num;i++)
        {
            buf[i]=HART_Stu.PREAMBLE[i];
        }        
        
        if(HART_Stu.START<0x10)
        {
            COM_Num=START_Num+2;
        }
        else
        {
            COM_Num=START_Num+6;
        }

        CHK_Num=COM_Num+HART_Stu.BCNT+2;
        buf[START_Num]=HART_Stu.START;

        for(i=0;i<COM_Num-START_Num-1;i++)
        {
            buf[START_Num+1+i]=HART_Stu.ADDR[i];
        }

        buf[COM_Num]=HART_Stu.COM;
        buf[COM_Num+1]=HART_Stu.BCNT;

        buf[CHK_Num]=HART_Stu.CHK;

        if(HART_Stu.BCNT>1 && (HART_Stu.START&0x0F)==0x06)
        {
            for(i=0;i<2;i++)
            {
                buf[COM_Num+2+i]=HART_Stu.STATUS[i];
            }
            for(i=0;i<HART_Stu.BCNT-2;i++)
            {
                buf[COM_Num+4+i]=HART_Stu.DATA[i];
            }
        }
        else
        {
            for(i=0;i<HART_Stu.BCNT;i++)
            {            
                buf[COM_Num+2+i]=HART_Stu.DATA[i];
            }
        }

        for(i=START_Num;i<CHK_Num;i++)
        {
            Check_Sum=Check_Sum^buf[i];
        }

        if(HART_Stu.CHK==Check_Sum)
        {
            return 1;
        }
        else
        {
            return -2;
        }
    }
    else
    {
        return -1;
    }

    return 0;
}

int main(void)
{
    unsigned char list[41]={0xFF,0xFF,0xFF,0xFF,0xFF,0x86,0xA6,0x06,0xBC,0x61,0x4E,0x01,0x07,0x00,0x00,0x06,0x40,0xB0,0x00,0x00,0x45};
    HART_Struct a;
    uint8_t buf[41];    
    memset(buf,0,sizeof(buf)/sizeof(buf[0]));
    a=trans_HART_to_Struct(list);
    printf("%02X\n",a.CHK);
    printf("%d\n",trans_HART_to_Buf(a,buf));
    printf("%02X\n",buf[8]);
    for(uint8_t i=0;i<41;i++)
    {
        if(buf[i]==list[i])
        {

        }
        else
        {
            printf("ERROR\n");
            break;
        }
    }
}

